﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Newtonsoft.Json.Linq;
using System.Linq;
using System.Diagnostics;
using System.IO;

namespace PachubeDataAccess.Models
{
    //public class DataStream<T> : DataStream
    //{
    //    public DataPoint<T> CurrentValue;
    //    public DataPoint<T> MaxValue;
    //    public DataPoint<T> MinValue;

    //    public IEnumerable<DataPoint<T>> DataPoints;
    //}


    public class DataStream
    {
        public string Id { get; set; }
        public string Url { get; set; }

        public Feed Parent { get; set; }

        public DataPoint<string> CurrentValue { get; set; }
        public DataPoint<string> MaxValue { get; set; }
        public DataPoint<string> MinValue { get; set; }

        public DateTime LastUpdated { get; set; }

        public IEnumerable<DataPoint<string>> DataPoints { get; set; }

        public event UpdatedHandler Updated;

        public string Chart1Day
        {
            get
            {
                return BuildChartUrl("1day", 360, 200);
            }
        }

        public string BuildChartUrl(string duration, int width, int height)
        {
            // let's remove the extension of the url
            string urlbase = this.Url.Remove(this.Url.IndexOf(".json"));
            return urlbase + ".png?width=" + width + "&height=" + height + "&colour=%23000000&duration=" + duration + "&show_axis_labels=true&detailed_grid=true";
        }

        public void Refresh()
        {
            if (!String.IsNullOrWhiteSpace(this.Url))
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(this.Url + "?duration=1day");
                req.Method = "GET";
                req.Headers["X-PachubeApiKey"] = Parent.ApiKey;

                try
                {
                    req.BeginGetResponse(state =>
                    {
                        try { 
                            WebResponse resp = (state.AsyncState as HttpWebRequest).EndGetResponse(state);
                            using (Stream s = resp.GetResponseStream())
                            {
                                byte[] data = new byte[s.Length];
                                s.Read(data, 0, (int)s.Length);
                                string resultAsString = new string(System.Text.Encoding.UTF8.GetChars(data));
                                JObject resultAsJson = JObject.Parse(resultAsString);
                                this.Id = (string)resultAsJson["id"];
                                this.MaxValue = new DataPoint<string> { Value = (string)resultAsJson["max_value"] };
                                this.MinValue = new DataPoint<string> { Value = (string)resultAsJson["min_value"] };
                                this.CurrentValue = new DataPoint<string> { Value = (string)resultAsJson["current_value"] };
                                if (Updated != null)
                                {
                                    Updated(this, new DataStreamUpdatedEventArgs() { DataStream = this });
                                }
                            }
                        }
                        catch(WebException ex)
                        {
                            Debug.WriteLine(ex.Message + ": " + (state.AsyncState as HttpWebRequest).RequestUri.ToString());
                        }
                    }, req);


                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                }
            }
        }

        //public static IEnumerable<DataStream> ParseJSON(int feedId, JToken json)
        public static IEnumerable<DataStream> ParseJSON(Feed parent, JToken json)
        { 
            return from ds in json
                   let id = (string)ds.SelectToken("id")
                   let at = (string)ds.SelectToken("at")
                   select new DataStream()
                   {
                       Id = id,
                       Parent = parent,
                       LastUpdated = (at != null) ? DateTime.Parse(at) : DateTime.MinValue,
                       Url = Resources.FeedsBaseUrl + "/" + parent.Id + "/datastreams/" + id + ".json",
                       CurrentValue = new DataPoint<string> { Value = (string)ds.SelectToken("current_value") },
                       MaxValue = new DataPoint<string> { Value = (string)ds.SelectToken("max_value") },
                       MinValue = new DataPoint<string> { Value = (string)ds.SelectToken("min_value") }
                   };
        }


        public delegate void UpdatedHandler(object sender, DataStreamUpdatedEventArgs e);
        public class DataStreamUpdatedEventArgs : EventArgs
        {
            public DataStream DataStream;
        }

    }


}
